package cn.com.huzo.webapp.controller;

import cn.com.huzo.common.util.ApplicationConfiguration;
import huzofw.common.web.controller.BaseFormController;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

/**
 * Controller class to upload Files.
 * <p>
 * @author 吴旭
 */
@Controller
public class FileUploadController extends BaseFormController {

    private final String DEFAULT_SUB_FOLDER_FORMAT_AUTO = "yyyyMMddHHmmss";   // 图片命名格式
    private final String uploadPath = (String) ApplicationConfiguration.getProperty("UploadPath");
    private final String browsePath = (String) ApplicationConfiguration.getProperty("BrowsePath");

    // @RequestBody FileUpload fileUpload
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "fileUpload.html",
            method = RequestMethod.POST,
            produces = {"application/xml", "application/json"})
    public @ResponseBody
    Map<String, ? extends Object> handleAjaxFileUpload(MultipartHttpServletRequest request)
            throws Exception {

        Map<String, Object> result = new HashMap();

        //1. build an iterator
        Iterator<String> uploadFiles = request.getFileNames();
        if (!uploadFiles.hasNext()) {
            result.put("error", "没有上传文件。");
            result.put("fileName", "");
            result.put("urlPath", "");
            return result;
        }
        MultipartFile mpf;

        //String guid = request.getParameter("guid");
        String dir = request.getParameter("dir");
        // the directory to upload to uploadPath + dir;
        //String uploadDir = getServletContext().getRealPath("/upload/" + dir);
        //String uploadDir = uploadPath + dir;
        String uploadDir = uploadPath + dir;

        // The following seems to happen when running jetty:run
        /*if (uploadDir == null) {
            String _newDir = request.getContextPath() + "/upload/" + dir;
            uploadDir = new File(_newDir).getAbsolutePath();
        }*/
        uploadDir += "/";
        // Create the directory if it doesn't exist
        File dirPath = new File(uploadDir);

        if (!dirPath.exists()) {
            dirPath.mkdirs();
        }

        //2. get each file
        while (uploadFiles.hasNext()) {
            mpf = request.getFile(uploadFiles.next());

            // copy file to local disk (make sure the path "e.g. D:/temp/files" exists)            
            try {
                //这里不必处理IO流关闭的问题,因为FileUtils.copyInputStreamToFile()方法内部会自动把用到的IO流关掉
                //此处也可以使用Spring提供的MultipartFile.transferTo(File dest)方法实现文件的上传
                FileUtils.copyInputStreamToFile(mpf.getInputStream(), new File(uploadDir, mpf.getOriginalFilename()));

                result.put("success", true);
                result.put("fileName", mpf.getOriginalFilename());
                String link = dir + "/"; //request.getContextPath() + "/upload/" + dir + "/";
                result.put("fileUrl", link + mpf.getOriginalFilename());
                result.put("fileDir", uploadPath + dir);
            } catch (IOException ex) {
                result.put("success", false);
                result.put("errorMsg", ex.getMessage());
            } 
        }

        return result;
    }

    /*
     * 上传图片
     */
    @RequestMapping(value = "uploadImg.html")
    public void uplodaImg(@RequestParam("upload") MultipartFile file,
            HttpServletRequest request, HttpServletResponse response) {
        try (PrintWriter out = response.getWriter()) {
            response.setContentType("text/html;charset=UTF-8");
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");

            String uploadDir = uploadPath + "ckimg/";
            String CKEditorFuncNum = request.getParameter("CKEditorFuncNum");
            String fileName = file.getOriginalFilename();
            String uploadContentType = file.getContentType();
            String expandedName;
            switch (uploadContentType) {
                case "image/pjpeg":
                case "image/jpeg":
                    // IE6上传jpg图片的headimageContentType是image/pjpeg，而IE9以及火狐上传的jpg图片是image/jpeg
                    expandedName = ".jpg";
                    break;
                case "image/png":
                case "image/x-png":
                    // IE6上传的png图片的headimageContentType是"image/x-png"
                    expandedName = ".png";
                    break;
                case "image/gif":
                    expandedName = ".gif";
                    break;
                case "image/bmp":
                    expandedName = ".bmp";
                    break;
                default:
                    out.println("<script type=\"text/javascript\">");
                    out.println("window.parent.CKEDITOR.tools.callFunction("
                            + CKEditorFuncNum + ",'',"
                            + "'文件格式不正确（必须为.jpg/.gif/.bmp/.png文件）');");
                    out.println("</script>");
                    return;
            }
            if (file.getSize() > 1024 * 1024 * 2) {
                out.print("<script type=\"text/javascript\">window.parent.CKEDITOR.tools.callFunction("
                        + CKEditorFuncNum + ",''," + "'文件大小不得大于2M');</script>");
                out.flush();
                return;
            }
            DateFormat df = new SimpleDateFormat(DEFAULT_SUB_FOLDER_FORMAT_AUTO);
            fileName = df.format(new Date()) + expandedName;
            FileUtils.copyInputStreamToFile(file.getInputStream(), new File(uploadDir, fileName));

            // 返回"图像"选项卡并显示图片  request.getContextPath()为web项目名  
            out.print("<script type=\"text/javascript\">window.parent.CKEDITOR.tools.callFunction("
                    + CKEditorFuncNum + ",'" + "ckimg/"
                    + fileName + "','');</script>");
            out.flush();
            out.close();
        } catch (IllegalStateException | NullPointerException e) {
            //e.printStackTrace();
        } catch (IOException e) {
            //e.printStackTrace();
        } catch (Exception e) {
            //e.printStackTrace();
        }
    }

    /**
     * 浏览图片
     *
     * @param modelMap
     * @param request
     * @param response
     */
    @RequestMapping(value = "browseImg.html")
    public void browseImg(ModelMap modelMap, HttpServletRequest request, HttpServletResponse response) {
        File folder;
        folder = new File(uploadPath + "ckimg");
        // 存储子目录 
        List<String> subFolderSet = new ArrayList();
        // 存储文件夹
        List<String> subFileerSet = new ArrayList();

        File[] subFiles = folder.listFiles();
        if (null != subFiles && 0 < subFiles.length) {
            for (File _file : subFiles) {
                if (_file.isDirectory()) {
                    //           subFolderSet.add(getDefaultFolderFromMueasRunningData(_file));
                } else {
                    subFileerSet.add(getFileName(_file.getName()));
                }
            }
        }

        String callback = request.getParameter("CKEditorFuncNum");
        PrintWriter out;

        response.setContentType("text/html");
        response.setCharacterEncoding("UTF-8");
        String outs = "<!DOCTYPE html>"
                + "<html>"
                + "<head>"
                + "<title>浏览图片</title>";

        outs += "<script type=\"text/javascript\" src=\"";
        outs += request.getContextPath();
        outs += "/scripts/jquery.min.js\" charset=\"utf-8\"></script>\n"
                + "<script type=\"text/javascript\" src=\"";
        outs += request.getContextPath();  //${rc.contextPath}
        outs += "/scripts/plugin/jquery.ui.wxpagination.js\" charset=\"utf-8\"></script>\n"
                + "<script type=\"text/javascript\" src=\"";
        outs += request.getContextPath();   //${rc.contextPath}
        outs += "/scripts/common/site.main.js\"></script>\n";
        outs += "<script type=\"text/ecmascript\" src=\"";
        outs += request.getContextPath();
        outs += "/scripts/views/20_oa/bulletin_ckeditor_pagination.js\"></script>\n";
        outs += "" + "</head>\n" + "<body>\n";
        try {
            out = response.getWriter();
            outs += "<style type='text/css'>\n"
                    + "li:hover {\n"
                    + "    color: #34ac83;\n"
                    + "    font-size: 19px;\n"
                    + "    cursor: pointer;\n"
                    + "}\n"
                    + "span {cursor:pointer;}\n"
                    + "</style>\n";

            outs += "<script type='text/javascript'>\n";

            // 定义点击选择js
            String choose = "function choose(obj){"
                    + "window.opener.CKEDITOR.tools.callFunction(" + callback + ", obj);"
                    + "window.close();"
                    + "}";
            outs += choose;
            //logger.info(choose);

            // 定义文件夹点击响应js
            String view = "function view(obj){"
                    + "window.location.href='/browse/mgmt?type=image&CKEditorFuncNum=" + callback + "&folder=' + obj;"
                    + "}";
            //logger.info(view);
            outs += view;
            outs += "</script>\n";

            // 如果是文件，则点击就选择文件到控件中
            if (0 < subFileerSet.size()) {
                outs += "<div id=\"grid__wrapper\" style=\"position:relative; top:3px; left:8px; margin-right:8px;\">\n";
                Integer i = 0;
                //以下部分功能在js中实现
                //         Iterator<String> subFileerSetIndex = subFileerSet.iterator();
                //         while(subFileerSetIndex.hasNext() && i < 5){
                //             String ftemp = subFileerSetIndex.next();
                //             i +=1;
                //             String f = "/erpimg/ckimg";      //////getDefaultFolderFromMueasRunningData(folder);
                //             String fileUrl = f + File.separator + ftemp;
                //             String rtnFileUrl = "ckimg/"  + ftemp;
                //             fileUrl = StringUtils.replace(fileUrl, "//", "/");
                //             String div4 = "<div style='width:150px;height:150px;float:left;word-break:break-all;padding:5px;background:#666699;margin:5px;'>"
                //                     + "<a href='javascript:void(0)' onclick=choose('"+ browsePath + rtnFileUrl+"')>"
                //                     + "<img style='border:none;width:145px;height:145px;' src='"+fileUrl+"' title='"+fileUrl+"'/>"
                //                     + "</a>"
                //                     + "</div>";    
                //logger.info(div4);
                //             outs += div4;
                //             if(logger.isDebugEnabled()){
                //                logger.debug("Adding file： " + fileUrl);
                //            }
                //        }
                outs += "</div>\n";
            }
            double c = (double) subFiles.length / (double) 15;          //每页默认显示15个图片
            outs += "<input id=\"TotalPages\" type=\"hidden\" value=\"" + Math.ceil(c) + "\" />\n";
            outs += "<input id=\"PageIndex\" type=\"hidden\" value=\"1\" />\n";
            outs += "<div id=\"wrapper__navbar\" class=\"panel__nav_strip\" style=\"position:absolute;margin-right:8px;width:500px;\">\n"
                    + "    <div style=\"position:relative; display:inline-block; padding:0px; height:30px; line-height:30px;\">\n"
                    + "        <span id=\"loading__indicator\"><i class=\"fa fa-refresh fa-fw\"></i></span>\n"
                    + "        显示 <select id=\"page-size\" onchange=\"thisPage.SetPageSize()\">\n"
                    + "                <option value=\"15\">15</option>\n"
                    + "                <option value=\"20\">20</option>\n"
                    + "                <option value=\"25\">25</option>\n"
                    + "            </select> 条 / 页\n"
                    + "        <span id=\"page-first\" class=\"p_first arrow page-first\" data-action=\"first\">首页</span>\n"
                    + "        <span id=\"page-previous\" class=\"p_previous arrow page-previous\" data-action=\"previous\">上一页</span>\n"
                    + "        <abbr id=\"page_indicator_block\" class=\"page_indicator_block\" _msh_page=\"1\" style=\"margin:0 10px; width:40px;\">1 of 7</abbr>\n"
                    + "        <span id=\"page-next\" class=\"p_next arrow page-next\" data-action=\"next\">下一页</span>\n"
                    + "        <span id=\"page-last\" class=\"p_last arrow page-last\" data-action=\"last\">尾页</span>\n"
                    + "        <input type=\"text\" id=\"curr-page\" class=\"curr-page\" style=\"margin-left:15px; width:36px;\" />\n"
                    + "        <input type=\"button\" name=\"btn_goto\" id=\"but_goto\" value=\"跳转\" class=\"act__button page-goto\" onclick=\"\"/>\n"
                    + "    </div>\n"
                    + "</div>\n";
            outs += "</body>\n";
            outs += "</html>";
            //logger.info(outs);
            out.println(outs);
            out.flush();
            out.close();
        } catch (IOException e) {
            //e.printStackTrace();
        }
    }

    /**
     * 获取输入文件路径或者目录路径中最后一级的名字，即可能是一个文件名，也可能是一个子目录的名字
     *
     * @param file
     * @return
     */
    private static String getFileName(String file) {
        String temp = file.replace("//", "/");
        String items[] = file.split("/");
        if (items.length > 0) {
            return items[items.length - 1];
        } else {
            return null;
        }
    }

    /**
     * 浏览公告板图片
     *
     * @param criterion
     * @return
     * @throws java.lang.Exception
     */
    @RequestMapping(value = "oa/bulletin/img/fetchForPage.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> fetchImgListForPage(@RequestBody final Map<String, Object> criterion) throws Exception {
        Integer pageIndex = MapUtils.getInteger(criterion, "PageIndex");
        Integer pageSize = MapUtils.getInteger(criterion, "PageSize");
        // 返回显示的图片文件名列表 
        Map<String, Object> _result = new HashMap();

        File folder;
        folder = new File(uploadPath + "ckimg");
        // 存储图片文件名 
        List<String> filesNameSet = new ArrayList();
        // 存储文件夹
        List<String> subFileerSet = new ArrayList();

        File[] subFiles = folder.listFiles();
        if (null != subFiles && 0 < subFiles.length) {
            for (File _file : subFiles) {
                if (_file.isDirectory()) {
                    //           subFolderSet.add(getDefaultFolderFromMueasRunningData(_file));
                } else {
                    subFileerSet.add(getFileName(_file.getName()));
                }
            }
        }

        // 如果是文件，则点击就选择文件到控件中
        if (0 < subFileerSet.size()) {
            Iterator<String> subFileerSetIndex = subFileerSet.iterator();
            Integer j = 0;
            while (subFileerSetIndex.hasNext() && j < pageIndex * pageSize) {
                String ftemp = subFileerSetIndex.next();
                if (j >= (pageIndex - 1) * pageSize) {
                    filesNameSet.add(ftemp);
                }
                j += 1;
            }
        }
        double c = (double) subFiles.length / (double) pageSize;
        _result.put("TotalPages", Math.ceil(c));
        _result.put("FilesNameList", filesNameSet);
        _result.put("PageIndex", pageIndex);
        _result.put("BrowsePath", browsePath);

        return _result;
    }
}
